package com.bootdo.common.utils;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 日期处理
 */
public class DateUtils {
    private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);
    private static final SimpleDateFormat dayOfDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat secondOfDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 计算距离现在多久，非精确
     *
     * @param date
     * @return
     */
    public static String getTimeBefore(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        } else if (hour > 0) {
            r += hour + "小时";
        } else if (min > 0) {
            r += min + "分";
        } else if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }

    /**
     * 计算距离现在多久，精确
     *
     * @param date
     * @return
     */
    public static String getTimeBeforeAccurate(Date date) {
        Date now = new Date();
        long l = now.getTime() - date.getTime();
        long day = l / (24 * 60 * 60 * 1000);
        long hour = (l / (60 * 60 * 1000) - day * 24);
        long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        String r = "";
        if (day > 0) {
            r += day + "天";
        }
        if (hour > 0) {
            r += hour + "小时";
        }
        if (min > 0) {
            r += min + "分";
        }
        if (s > 0) {
            r += s + "秒";
        }
        r += "前";
        return r;
    }
    
    /**
     * @return 当天时间加一天，返回"yyyy-MM-dd"格式
     */
    public static String addOneDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return dayOfDateFormat.format(calendar.getTime());
    }

    /**
     * @return 当天时间加一月，返回"yyyy-MM-dd"格式
     */
    public static String addOneMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        return dayOfDateFormat.format(calendar.getTime());
    }

    /**
     * @param dayNumber 加的天数     * @return 返回当天时间添加几天之后的时间,返回"yyyy-MM-dd"格式
     */
    public static String addFewDays(int dayNumber) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, dayNumber);
        return dayOfDateFormat.format(calendar.getTime());
    }

    /**
     * @param dateString 需要转换成时间格式的日期字符串     * @return 返回字符串转换成的时间
     */
    public static Date stringToDate(String dateString) {
        ParsePosition parsePosition = new ParsePosition(0);
        if (dateString.contains(" ")) {
            return secondOfDateFormat.parse(dateString, parsePosition);
        } else {
            return dayOfDateFormat.parse(dateString, parsePosition);
        }
    }

    /**
     * @param date 需要转换成字符串格式的日期     * @return 返回"yyyy-MM-dd"格式的转换后的字符串
     */
    public static String dateToShotString(Date date) {
        return dayOfDateFormat.format(date);
    }

    /**
     * @param date 需要转换成字符串格式的日期     * @return 返回"yyyy-MM-dd HH:mm:ss"格式的转换后的字符串
     */
    public static String dateToLongString(Date date) {
        return secondOfDateFormat.format(date);
    }

    /**
     * @param dateString 需要获取0点的时间字符串,如果获取当天0点,传null即可     * @return 返回"yyyy-MM-dd HH:mm:ss"格式的某天0点字符串
     */
    public static String getZeroTime(String dateString) {
        if (StringUtils.isBlank(dateString)) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            return secondOfDateFormat.format(calendar.getTime());
        } else {
            Date date = stringToDate(dateString);
            return dateToLongString(date);
        }
    }
    /**
     * 获取日期是星期几
     */
    public static String dateToWeek(Date date) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance(); // 获得一个日历
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。
        if (w < 0)
            w = 0;
        return weekDays[w];
    }
    
    /**
     * 获取当月的 天数
     */
    public static int getCurrentMonthDay()
    {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 根据 年、月 获取对应的月份 的 天数
     */
    public static int getDaysByYearMonth(int year, int month)
    {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 根据日期 找到对应日期的 星期几
     *
     * @param date 比如传参：2018-07-13 将返回“周五”
     */
    public static String getDayOfWeekByDate(String date)
    {
        String dayOfweek = "-1";
        try
        {
            SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
            Date myDate = myFormatter.parse(date);
            SimpleDateFormat formatter = new SimpleDateFormat("E");
            String str = formatter.format(myDate);
            dayOfweek = str;
        }
        catch (Exception e)
        {
            System.out.println("错误!");
        }
        return dayOfweek;
    }
    
    /**
     * 使用用户格式提取字符串日期
     * 
     * @param strDate
     *            日期字符串
     * @param pattern
     *            日期格式
     * @return
     */
    public static Date parse(String strDate, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        try {
            return df.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
    

	/**
	* 日期转换成字符串
	* @param date
	* @return str
	*/
	public static String DateToStr(Date date) {

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 String str = format.format(date);
 return str;
	}
	
	/**
	* 字符串转换成日期
	* @param str
	* @return date
	*/
	public static Date StrToDate(String str) {

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	 Date date = null;
	 try {
	 date = format.parse(str);
	 } catch (ParseException e) {
	 e.printStackTrace();
	 }
	 return date;
}

	//java获取当前月的天数
	public static int getDayOfMonth(){
	   Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
	   int day=aCalendar.getActualMaximum(Calendar.DATE);
	   return day;
	}
	//java获取当时间所在月份的第几天
    public int getDayint(Date date) {
   
		Calendar ca=Calendar.getInstance();
		ca.setTime(date);
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
		
		String st=sdf.format(date);
		int i=ca.get(Calendar.DAY_OF_YEAR);
		int a=ca.get(Calendar.DAY_OF_MONTH);
		System.out.println("当前时间是："+st+";一年中的"+i+"一个月中的"+a);
		return a;

    }

    //java获取当前月每天的日期
    public static List<Date> getDayListOfMonth() throws ParseException {
    	SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd");
		
        List<Date> list = new ArrayList<Date>();
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        int year = aCalendar.get(Calendar.YEAR);//年份
        int month = aCalendar.get(Calendar.MONTH) + 1;//月份
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            String aDate = String.valueOf(year)+"/"+month+"/"+i;
            list.add(sdf.parse(aDate));
        }
        return list;
    }

    public static List<Date> getDayListOfMonthup() throws ParseException {
    	SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd");
		
        List<Date> list = new ArrayList<Date>();
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        int year = aCalendar.get(Calendar.YEAR);//年份
        int month = aCalendar.get(Calendar.MONTH) + 1;//月份
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            String aDate = String.valueOf(year)+"/"+month+"/"+i;
            list.add(sdf.parse(aDate));
        }
        return list;
    }
    

    /**
     * 获取上一个月
     * 
     * @return
     */
    public static String getLastMonth() {
        Calendar cal = Calendar.getInstance();
        cal.add(cal.MONTH, -1);
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMM");
        String lastMonth = dft.format(cal.getTime());
        return lastMonth;
    }
    
    /**
     * 获取任意时间的上一个月
     * 描述:<描述函数实现的功能>.
     * @param repeatDate
     * @return
     */
    public static String getLastMonth(String repeatDate) {
        String lastMonth = "";
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat dft = new SimpleDateFormat("yyyyMM");
        int year = Integer.parseInt(repeatDate.substring(0, 4));
        String monthsString = repeatDate.substring(4, 6);
        int month;
        if ("0".equals(monthsString.substring(0, 1))) {
            month = Integer.parseInt(monthsString.substring(1, 2));
        } else {
            month = Integer.parseInt(monthsString.substring(0, 2));
        }
        cal.set(year,month-2,Calendar.DATE);
        lastMonth = dft.format(cal.getTime());
        return lastMonth;
    }
    
    /**
     *  java 获取 获取某年某月 所有日期（yyyy-mm-dd格式字符串）
     * @param year
     * @param month
     * @return
     */
    public static List<Date> getMonthFullDay(int year , int month){
        SimpleDateFormat dateFormatYYYYMMDD = new SimpleDateFormat("yyyy-MM-dd");
        List<Date> fullDayList = new ArrayList<Date>();
        // 获得当前日期对象
        Calendar cal = Calendar.getInstance();
        cal.clear();// 清除信息
        cal.set(Calendar.YEAR, year);
        // 1月从0开始
        cal.set(Calendar.MONTH, month-1 );
        // 当月1号
        cal.set(Calendar.DAY_OF_MONTH,1);
        int count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 1; j <= count ; j++) {
            fullDayList.add(cal.getTime());
            cal.add(Calendar.DAY_OF_MONTH,1);
        }
        return fullDayList;
    }
    // date类型转换为String类型
    // formatType格式为yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
    // data Date类型的时间
    public static String dateToString(Date data, String formatType) {
    return new SimpleDateFormat(formatType).format(data);
    }
   
    // long类型转换为String类型
    // currentTime要转换的long类型的时间
    // formatType要转换的string类型的时间格式
    public static String longToString(long currentTime, String formatType)
    throws ParseException {
    Date date = longToDate(currentTime, formatType); // long类型转成Date类型
    String strTime = dateToString(date, formatType); // date类型转成String
    return strTime;
    }
   
    // string类型转换为date类型
    // strTime要转换的string类型的时间，formatType要转换的格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日
    // HH时mm分ss秒，
    // strTime的时间格式必须要与formatType的时间格式相同
    public static Date stringToDate(String strTime, String formatType)
    throws ParseException {
    SimpleDateFormat formatter = new SimpleDateFormat(formatType);
    Date date = null;
    date = formatter.parse(strTime);
    return date;
    }
   
    // long转换为Date类型
    // currentTime要转换的long类型的时间
    // formatType要转换的时间格式yyyy-MM-dd HH:mm:ss//yyyy年MM月dd日 HH时mm分ss秒
    public static Date longToDate(long currentTime, String formatType)
    throws ParseException {
    Date dateOld = new Date(currentTime); // 根据long类型的毫秒数生命一个date类型的时间
    String sDateTime = dateToString(dateOld, formatType); // 把date类型的时间转换为string
    Date date = stringToDate(sDateTime, formatType); // 把String类型转换为Date类型
    return date;
    }
   
    // string类型转换为long类型
    // strTime要转换的String类型的时间
    // formatType时间格式
    // strTime的时间格式和formatType的时间格式必须相同
    public static long stringToLong(String strTime, String formatType)
    throws ParseException {
    Date date = stringToDate(strTime, formatType); // String类型转成date类型
    if (date == null) {
    return 0;
    } else {
    long currentTime = dateToLong(date); // date类型转成long类型
    return currentTime;
    }
    }
   
    // date类型转换为long类型
    // date要转换的date类型的时间
    public static long dateToLong(Date date) {
    return date.getTime();
    }
    
    public static Date getSysDate() {
		Date date = new Date(System.currentTimeMillis());
		return date;
    }
}
